<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>H8/300 Application Binary Interface for GCC</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>
<h1>H8/300 Application Binary Interface for GCC</h1>

<h2>Glossary</h2>

<dl>
<dt>aggregate</dt>
<dd>struct and union in C or C++, and class in C++.</dd>

<dt>libcall</dt>
<dd>GCC's internal library function to implement features not available
on the target architecture, such as the 32-bit-by-32-bit
multiplication on H8/300.</dd>

<dt>prologue</dt>
<dd>The initial part of a subroutine that saves registers that should
be preserved across a call and allocates stack areas for local
variables.</dd>

<dt>scalar</dt>
<dd>The antonym of aggregate, such as char, short, and int.</dd>
</dl>

<h2>Argument Passing</h2>

<h3>With <code>-mno-quickcall</code></h3>

<p>With <code>-mno-quickcall</code>, every argument is pushed onto the
stack.</p>

<h3>Without <code>-mno-quickcall</code></h3>

<h4>Functions with Fixed-Length Arguments</h4>

<p>The first argument goes into ER0 or R0 in case of 16-bit argument.
Likewise, the second and third goes into ER1 and ER2, respectively.
The rest of the arguments are pushed onto the stack, from the last to
first.</p>

<p>If a 32-bit argument is to be passed on registers on H8/300, R0
contains the upperhalf, and R1 contains the lowerhalf of the argument.
Likewise, if a 64-bit argument is to be passed on registers on H8/300H
or H8S, ER0 contains the upperhalf, and ER1 contains the lowerhalf of
the argument.</p>

<p>These registers are always filled when calling functions with
fixed-length arguments.  For example, if one wishes to pass two
arguments of type long on H8/300, the first argument is stored into a
pair of R0 and R1.  The upper half of the second argument is stored
into R2.  The lower half is pushed onto the stack.</p>

<p>If the return value is of an aggregate type, an invisible argument
will take the first argument.  For details, see Function Value
below.</p>

<p>Every stack push is rounded to a multiple of 2 bytes on H8/300 and
of 4 bytes on H8/300H and H8S.  If the size of a value pushed onto the
stack is different from the size of an actual push, a padding is added
downward.  For example, if 2 bytes of data, 0x1234, are to be pushed
onto the stack on H8/300H, 4 bytes are pushed like so:</p>

<table class="border">
<tr><td>sp + 3</td><td>0x34</td></tr>
<tr><td>sp + 2</td><td>0x12</td></tr>
<tr><td>sp + 1</td><td>padding (unknown value)</td></tr>
<tr><td>sp + 0</td><td>padding (unknown value)</td></tr>
</table>

<p>As an exception, a libcall will use R0 through R3 on H8/300 or ER0
through ER3 on H8/300H and H8S to pass arguments before resorting to
the stack.</p>

<h4>Functions with Variable-Length Arguments</h4>

To be documented.

<h2>Function Value</h2>

<p>On H8/300, the scalar function value no larger than 4 bytes in size
is returned in R0 or a pair of R0 and R1.  If a pair of R0 and R1 is
used to return the function value, R0 contains the upper half and R1
contains the lower half of the value.</p>

<p>On H8/300H and H8S, the scalar function value no larger than 8
bytes in size is returned in ER0 or a pair of ER0 and ER1.</p>

<p>Otherwise, the function value is always returned in memory.
Specifically, the caller allocates an instance of the aggregate type
and passes a pointer to the instance as an invisible argument.  The
caller stores the function value into the memory location pointed to
by the invisible pointer.  To illustrate, the following two functions
behave identically (and may even be compiled into exactly the same
assembly code with optimization enabled).</p>

<pre>
struct s { int a; };

struct s
foo (void)
{
  struct s s = { 0 };
  return s;
}

void
bar (struct s *p)
{
  p->a = 0;
}
</pre>

<h2>Call Clobbered Registers</h2>

<p>R0 through R3 are call clobbered on H8/300H and H8S.  Likewise, ER0
through ER3 are call clobbered on H8/300H and H8S.  These registers
are clobbered regardless of the number of the registers used for
argument passing.</p>

<h2>Frame Pointer</h2>

<p>On H8/300, R6 is used as the frame pointer.  On H8/300H and H8S,
ER6 is used as the frame pointer.  <code>-fomit-frame-pointer</code>
can be used to eliminate the use of the frame pointer in favor of the
stack pointer.</p>

<h2>Bit-Field</h2>

<p>The memory location containing a bit-field is filled from MSB to
LSB.  In the following example, <code>a</code> will take bit 7, MSB.
<code>b</code> will take bit 6 and bit 5.</p>

<pre>
struct s {
  int a:1;
  int b:2;
};
</pre>

<h2>Structure Alignment</h2>

<p>Unless <code>__attribute__ ((packed))</code> is attached to the
declaration of a struct, each structure member is aligned to a
multiple of 2 bytes on H8/300 and of 4 bytes on H8/300H and H8S.</p>

<h2>Stack Frame Layout</h2>

<h3>From gcc-2.6? up to GCC-3.4</h3>

<p>Immediately after the prologue is setup, the stack frame layout is
as follows:</p>

<table class="border">
<tr>
  <th>Address</th>
  <th>Description</th>
  <th>Size on H8/300</th>
  <th>Size on H8/300H and H8S<br />(Normal Mode)</th>
  <th>Size on H8/300H and H8S<br />(Advanced Mode)</th>
  <th>Pointed to by</th>
</tr>
<tr>
  <td>High</td>
  <td>Arguments<br />(if any)</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Program Counter</td>
  <td>2 bytes</td>
  <td>2 bytes</td>
  <td>4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Saved Frame Pointer</td>
  <td>2 bytes</td>
  <td>4 bytes</td>
  <td>4 bytes</td>
  <td>R6 or ER6</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Locals</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>Low</td>
  <td>Saved Registers</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>R7 or ER7<br />(points to the lowest address)</td>
</tr>
</table>

<ul>
  <li>The caller is responsible for pushing arguments and deallocating
  the stack area for those arguments.</li>

  <li>Registers are saved in the ascending order of the register
  number.</li>

  <li>If R6 or ER6 is used as a scratch register rather than as the
  frame pointer, the register is saved in "Saved Registers"
  above.</li>

</ul>

<h3>GCC 4.0 and later</h3>

<p>Currently, the stack frame layout, subject to change, is as
follows:</p>

<table class="border">
<tr>
  <th>Address</th>
  <th>Description</th>
  <th>Size on H8/300</th>
  <th>Size on H8/300H and H8S<br />(Normal Mode)</th>
  <th>Size on H8/300H and H8S<br />(Advanced Mode)</th>
  <th>Pointed to by</th>
</tr>
<tr>
  <td>High</td>
  <td>Arguments<br />(if any)</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Program Counter</td>
  <td>2 bytes</td>
  <td>2 bytes</td>
  <td>4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Saved Frame Pointer<br />(if any)</td>
  <td>2 bytes</td>
  <td>4 bytes</td>
  <td>4 bytes</td>
  <td>R6 or ER6</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>Saved Registers</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>Low</td>
  <td>Locals</td>
  <td>Multiple of 2 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>Multiple of 4 bytes</td>
  <td>R7 or ER7<br />(points to the lowest address)</td>
</tr>
</table>

<ul>
  <li>The caller is responsible for pushing arguments and deallocating
  the stack area for those arguments.</li>

  <li>Registers are saved in the ascending order of the register
  number.</li>

  <li>If R6 or ER6 is used as a scratch register rather than as the
  frame pointer, the register is saved in "Saved Registers"
  above.</li>

</ul>

<h2>Complex Numbers</h2>

To be documented.

<h2>Static Chain</h2>

To be documented.

</body>
</html>
